﻿using LitJson;
using RestAPI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TopVisionLog;
using TopVisionVideoStream.TopVisionCenter;

namespace TopVisionVideoStream
{
    public static class VideosManager
    {
        //public delegate void VideoPathsHandler(List<ConfVideo> confVideos);

        //public static VideoPathsHandler VideoPathsEvent;

        public delegate void ERRORVIdeoListHandler();

        public static event ERRORVIdeoListHandler ERRORVideoList;


        public static List<ConfVideo> VideoList = new List<ConfVideo>();

        public static bool IsDispose = false;

        public static bool Enable = true;

        public static bool AutoUpdate = true;

        public static string recordPathHeader;



        // 更新视频列表 线程
        private static Task TaskUpdateConfVideos;
        private static CancellationTokenSource ctsTaskUpdateConfVideos;
        private static int errVideoList;
        private static int maxRetry = 5;

        public async static void UpdateConfVideos()
        {
            if (Enable & AutoUpdate)
            {
                await UpdateConfVideosCancel();
                ctsTaskUpdateConfVideos = new CancellationTokenSource();

                TVLog.WriteLine("开始更新视频列表 ==================");
#if DEBUG
                Console.WriteLine("开始更新视频列表 ==================");
#endif

                TaskUpdateConfVideos = Task.Factory.StartNew(UpdateConfVideosHttp, ctsTaskUpdateConfVideos.Token);
            }
        }

        private static void UpdateConfVideosHttp()
        {
            Mzwangetvideopath mzvp = new Mzwangetvideopath(Configuration.CompanyID);

            while (!ctsTaskUpdateConfVideos.IsCancellationRequested)
            {
                var ret = mzvp.Call(PostResponse);

                if (ret == WebRequestError.类型错误) PostResponse(null);

                TaskUpdateConfVideos.Wait(3000);
            }

            ctsTaskUpdateConfVideos.Dispose();

            ctsTaskUpdateConfVideos = null;
        }

        public static void UpdateConfVideosHttpShoot()
        {
            Mzwangetvideopath mzvp = new Mzwangetvideopath(Configuration.CompanyID);

            mzvp.Call(PostResponse);
        }

        public async static Task UpdateConfVideosCancel()
        {
            if (ctsTaskUpdateConfVideos != null)
            {
                TVLog.WriteLine("取消更新视频列表 ==================");
#if DEBUG
                Console.WriteLine("取消更新视频列表 ==================");
#endif
                ctsTaskUpdateConfVideos.Cancel();

                if (TaskUpdateConfVideos != null)
                    while (!TaskUpdateConfVideos.IsCompleted)
                    {
                        await Task.Delay(100);
                    }
            }

            return;
        }

        //public static void GetVideoPath(VideoPathsHandler handler)
        //{
        //    if (Configuration.CompanyID == null) return;
        //    VideoPathsEvent = handler;
        //    Mzwangetvideopath mzvp = new Mzwangetvideopath(Configuration.CompanyID);
        //    mzvp.Call(PostResponse);
        //}

        private static void PostResponse(string response)
        {
            try
            {
                if (string.IsNullOrEmpty(response)) throw new Exception("video list result is null");

                ConfVideoResult cvr = JsonMapper.ToObject<ConfVideoResult>(response);
                VideoList = cvr.data;
                for (int i = 0; i < VideoList.Count; i++)
                {
                    VideoList[i].createtime = VideoList[i].createtime.Replace(".", "-");
                    VideoList[i].starttime = VideoList[i].starttime.Replace(".", "-");
                    VideoList[i].thumbnail = recordPathHeader + VideoList[i].thumbnail;
                    VideoList[i].confrecord = recordPathHeader + VideoList[i].confrecord;
                }
                errVideoList = 0;
                //VideoPathsEvent?.Invoke(VideoList);
            }
            catch (Exception ex)
            {

                TVLog.WriteLine("Cong Vdieos Result error ; " + ex.Message + "\r\n" + response);
#if DEBUG
                Console.WriteLine("Conf Video Result error:" + ex.Message + "\r\n" + response);
#endif
                errVideoList++;
                if (errVideoList > maxRetry)
                {
                    //await UpdateConfVideosCancel();

                    errVideoList = 0;

                    if (ERRORVideoList != null)
                    {
                        ERRORVideoList.Invoke();
                    }
                }
            }
        }

        //public async static void UpdateVideoList()
        //{
        //    while (!IsDispose)
        //    {
        //        GetVideoPath(null);
        //        await Task.Delay(5000);
        //    }
        //}


        public async static void Dispose()
        {
            IsDispose = true;

            await UpdateConfVideosCancel();
        }
    }

    /// <summary>
    /// 视频请求列表
    /// </summary>
    public class ConfVideoResult
    {
        /// <summary>
        /// 请求数据成功!
        /// </summary>
        public string msg { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public int code { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public List<ConfVideo> data { get; set; }

        public ConfVideoResult()
        {
            msg = "";
            code = 0;
            data = new List<ConfVideo>();
        }
    }

    /// <summary>
    /// 视频信息
    /// </summary>
    public class ConfVideo : IEquatable
    {
        /// <summary>
        /// 
        /// </summary>
        public string callid { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string confid { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string confrecord { get; set; }
        /// <summary>
        /// Web发起视频会议
        /// </summary>
        public string confsubject { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string createtime { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string segid { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string starttime { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string status { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string zwanid { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string zwannumber { get; set; }
        /// <summary>
        /// 视频缩略图
        /// </summary>
        public string thumbnail { get; set; }

        // 个人中心

        public string endtime { get; set; }

        public string number { get; set; }

        public string confrtmpurl { get; set; }

        public string confhlsurl { get; set; }

        public string conftype { get; set; }

        public string realName { get; set; }


        public override bool Equals(object obj)
        {
            if (obj == null) return false;

            if ((obj as ConfVideo) == null) return false;

            return confid == (obj as ConfVideo).confid;
        }

        //add this code to class ThreeDPoint as defined previously
        //
        //public static bool operator ==(ConfVideo a, ConfVideo b)
        //{
        //    // If both are null, or both are same instance, return true.
        //    if (System.Object.ReferenceEquals(a, b))
        //    {
        //        return true;
        //    }

        //    // If one is null, but not both, return false.
        //    if (((object)a == null) || ((object)b == null))
        //    {
        //        return false;
        //    }

        //    // Return true if the fields match:
        //    return a.confid == b.confid;
        //}

        //public static bool operator !=(ConfVideo a, ConfVideo b)
        //{
        //    return !(a.confid == b.confid);
        //}

        public override int GetHashCode()
        {
            return confid.GetHashCode();
        }
    }
}
